import { Injectable } from "@angular/core";
import { QueryEncoder } from "@angular/http";
declare var jsPDF: any;
declare var html2canvas: any;

import { LocalStorage } from "../../tools/local.storage";
import { SessionStorage } from "../../tools/session.storage";
import notify from "devextreme/ui/notify";
declare var $: any;
/**
 * 工具
 */
export class ParameterUtils {
  static sessionStorage: SessionStorage = new SessionStorage();
  static localStorage: LocalStorage = new LocalStorage();
  static queryEncoder: QueryEncoder = new QueryEncoder();

  constructor() {}

  /**
   * 简单json对象装换为查询字符串
   * @Time 2017-12-26
   * @author Zhong Yang
   * @param json 查询Form表单封装成的对象
   */
  static json2Params(json: object): string {
    let retArr: Array<string> = [];
    let ret: string = "";
    for (var p in json) {
      if (typeof json[p] == "function") {
        continue;
      }
      let notNull: boolean =
        json[p] != "" && json[p] != null && json[p] != undefined;
      if (typeof json[p] == "string" && json[p] != undefined && notNull) {
        retArr.push(p + "=" + json[p]);
      } else if (json[p] instanceof Date && notNull) {
        retArr.push(p + "=" + json[p].getTime());
      } else {
        console.log("arry[" + p + "] is not searchFormData property.");
      }
    }
    ret = retArr.join("&");
    return ret;
  }

  /**
   * 日期型格式转化
   */
  static forChangeDate(json: Object) {
    for (var p in json) {
      if (typeof json[p] == "function") {
        continue;
      }
      let notNull: boolean =
        json[p] != "" && json[p] != null && json[p] != undefined;
      if (json[p] instanceof Date && notNull) {
        json[p] = json[p].getTime();
      }
    }
  }

  /**
   * 日期型格式转化
   */
  static forChangeDayDate(json: Object) {
    for (var p in json) {
      if (typeof json[p] == "function") {
        continue;
      }
      let notNull: boolean =
        json[p] != "" && json[p] != null && json[p] != undefined;
      if (json[p] instanceof Date && notNull) {
        json[p] = new Date(
          json[p].getFullYear(),
          json[p].getMonth(),
          json[p].getDate()
        );
        json[p] = json[p].getTime();
      }
    }
  }

  /**
   * 可编辑DataGrid中的 修改过的数据转变为JSON数组
   * @param gridChangeData 修改过的grid数据
   * @param primaryKey 主键名称
   * @Time 2017-12-27
   * @author Zhong Yang
   * @return void
   */
  static gridChangeData2JSON(
    gridChangeData: Array<any>,
    primaryKey: string
  ): Array<Object> {
    let batchRowsData: Array<Object> = new Array<Object>();
    gridChangeData.forEach((rowData) => {
      var keyValue = rowData.key[primaryKey];
      let retArr: Array<string> = [];
      let ret: string = "";
      let newData = rowData.newData;
      retArr.push('"' + primaryKey + '"' + ":" + '"' + keyValue + '"');

      for (var p in newData) {
        if (typeof newData[p] == "function") {
          continue;
        }
        if (typeof newData[p]! == "string") {
          retArr.push('"' + p + '"' + ":" + '"' + newData[p] + '"');
        } else if (newData[p]! instanceof Date) {
          retArr.push('"' + p + '"' + ":" + '"' + newData[p].getTime() + '"');
        } else {
          console.log("arry[" + p + "] is not searchFormData property.");
        }
      }
      ret = retArr.join(",");
      batchRowsData.push(JSON.parse("{" + ret + "}"));
    });
    return batchRowsData;
  }
  /**
   * 数据非空判断
   */
  static parameterIsNull(parameter) {
    let isNull: boolean = true;

    if (parameter != "" && parameter != null) {
      isNull = false;
    }

    return isNull;
  }
  /**
   * 出生日期校验  (评标)年龄不得低于32岁/(核实)年龄不得低于30岁 不大于60岁
   */
  static hsbirthMax: Date = new Date(
    new Date().getFullYear() - 30,
    new Date().getMonth(),
    new Date().getDate()
  );
  static birthMax: Date = new Date(
    new Date().getFullYear() - 32,
    new Date().getMonth(),
    new Date().getDate()
  );
  static birthMin: Date = new Date(
    new Date().getFullYear() - 60,
    new Date().getMonth(),
    new Date().getDate()
  );
  /**
   * 非法字符校验
   */
  static pat: string = "^[a-zA-Z0-9\u4e00-\u9fa5]+$";

  //文件特殊字符正则
  static filepten: any = new RegExp(
    /^.*[(/)|(\\\\\\\\)|(!)|(#)|(%)|(\\\\*)|(\\\")|(\\\')|(^)|($)|(?)].*$/
  );
  /**
   * 组织机构非法字符校验允许输入（） () · .
   */
  static patt: string = "^[a-zA-Z0-9\u4e00-\u9fa5（）().·]+$";
  /**
   * 基础数据代码名称校验
   */
  static flag: any = /^[\u4E00-\u9FA5A-Za-z0-9\-\.\(\)\uff08\uff09]+$/;
  /**
   * 非法字符校验 允许输入（）()
   */
  static patkh: string = "^[a-zA-Z0-9\u4e00-\u9fa5()（）]+$";
  static patNew: string = "^[^\\\\]+$";

  // 项目名称项目编号正则校验
  static patForPrj: String =
    "^[a-zA-Z0-9\u4e00-\u9fa5\\_ \\- () （）/ \\\\ \\+ \\— \\±]+$";
  /**
   *  日期格式正则
   */
  static dateRule: any = /^(0[1-9]|[12][0-9]|3[01])|(0[1-9]|[12][0-9]|30)|(0[1-9]|[1][0-9]|2[0-8])\/(0[13578]|1[02])|(0[469]|11)|02\/[0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3}$/;

  static imgPath: string = "exp/";
  //个人照片
  static imgPhotoPath: string = "exp/photo/";
  // 身份证
  static imgIdnumberPath: string = "exp/idnumber/";
  // 专业技术资格证书（按照年月存储）
  static imgMajorcertPath: string = "exp/majorcert/";
  //最高学位证书
  static imgMaxdegcertPath: string = "exp/maxdegcert/";
  // 就业学历证书
  static imgJobeducertPath: string = "exp/jobeducert/";
  // 最高学历证书
  static imgMaxeducertPath: string = "exp/maxeducert/";
  // 业绩资格证书
  static imgQualcertPath: string = "exp/qualcert/";
  // 获奖情况
  static imgWinprizePath: string = "exp/winprize/";
  // 著作情况
  static imgWorkmesPath: string = "exp/workmes/";
  // 研究成果
  static imgStudymesPath: string = "exp/studymes/";

  /**
   * 模糊查询 身份证号正则校验 可以输入数字 和 字母X
   */
  static idCardRule: any = /\d*([0-9]|[X])$/;
  /**
   * 注册页面身份证号输入校验
   */

  static registerIdCardRule: any = /^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9X]$/;
  /**
   *  注册页面邀请码输入校验
   */
  static registerInvtCodeRule: any = /^[0-9a-zA-Z]{6,15}$/;
  /**
   * 注册页面用户名输入校验
   */
  static registerAccountNameRule: any = /^(?!\d{11}$)[\da-zA-Z_]{6,16}$/;

  /**
   * 设置密码正则校验，注册、重置密码
   */
  static secretRule: any = /(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=([!-~]+)[^a-zA-Z0-9])^.+$/;
  /**
   * 注册页面手机号输入校验
   */
  static registerTelephoneRule: any = /^[1][3,4,5,7,8][0-9]{9}$/;
  //数字正则
  static numRule: any = /^[0-9]*$/;
  //账户管理姓名正则--只能输入汉字最大长度7
  static accountNameRule: any = /^([\u4e00-\u9fa5]){1,7}$/;
  /**
   * 注册页面验证码输入校验
   */
  static icodeRule: any = /^[0-9]{6}$/;
  /**
   * 账户管理
   */
  static accountPat: string = "[^!@#$%^&*~'_,.]";
  /**
   * 银行卡 正则校验
   */
  static BankIdRule: any = /^[0-9]{15,19}$/;
  /**
   * 邮政编号正则    原始/^[1-9]{1}[0-9]{5}$/;
   */
  static EMSNumRule: any = /^[0-9]{6}$/;
  /**
   * 固定电话格式正则
   */
  static telRule: any = /^((\d{3})-)\d{8}$|((\d{4})-)\d{7}$|((\d{4})-)\d{8}$/;
  /**
   * 手机号正则校验
   */
  static telephoneRule: any = /^(13[0-9]|14[579]|15[0-3,5-9]|16[6]|17[0135678]|18[0-9]|19[89])\d{8}$/;
  /**
   * 汉子姓名校验 只能输入汉字英文.·
   */
  static nameRule: any = /^[\u4E00-\u9FA5A-Za-z.·]+$/;
  //专家资格证书编号正则 可以输入汉字字母数字和-,（）()

  static certNoRule: any = /^[\u4E00-\u9FA5A-Za-z0-9\-\.\(\)\uff08\uff09]+$/;

  //正则 可以输入字母数字和.和·
  static commonRule: any = /^[A-Za-z0-9.·]+$/;
  /**
   * 培训项目管理培训内容正则
   */
  static trainCountRule: string =
    "^[a-zA-Z0-9\u4e00-\u9fa5\u005b-u005d,.!:?‘’<> ()（）《》、，。！：？“” 、，。！:：？ \\- _ / “” \" ; ；' ‘’+-±]+$";

  static patRule: string =
    "^[a-zA-Z0-9\u4e00-\u9fa5\u005b-u005d,.!:?‘’()（）《》、，。！：？“” 、，。！:：？ \\- _ / “” \" ; ；' ‘’+-±]+$";
  //培训项目管理 项目名称正则
  static prjNameRule: any = /^([0-9a-zA-Z\u4e00-\u9fa5、，+-±《》（）.,()]){1,50}$/;
  //模版管理内容正则--几乎包含所有中英文符号
  static patternTmpl: string =
    "^[a-zA-Z0-9\u4e00-\u9fa5\u005b-u005d,.!@#￥%&*:?‘’<> ()（）《》、，。！@#￥%&*：？“” 、，。！:：？ \\- _ / “” \" ; ；' ‘’+-]+$";
  //培训情况成绩正则
  static scoreRule: string = "^[a-zA-Z0-9\u4e00-\u9fa5\u005b-u005d]+$";
  //评标专业结构管理冻结原因正则
  static frozenReason: string =
    "^[a-zA-Z0-9\u4e00-\u9fa5\u005b-u005d,.!@#￥%&*:?‘’<> ()（）《》、，。！@#￥%&*：？“” 、，。！:：？ \\- _ / “” \" ; ；' ‘’+-]+$";
  //输入值只能为大于0或者正数，两位小数，其他符号不可输入。
  static money: any = /(^[1-9]{1}[0-9]{0,3}$)|(^[0-9]{1,4}\.[0-9]{0,2}$)/;
  //数字字母-_
  static patCode: any = /^[A-Za-z0-9-_]+$/;
  //数字字母-括号
  static patName: any = /^[A-Za-z0-9\u4e00-\u9fa5-()（）]+$/;
  //文件名称允许输入
  static fileNamePat: any = /^[A-Za-z0-9\u4e00-\u9fa5-_()（）]+$/;

  //@date 20200429
  //@author niushengsheng
  //特殊字符正则
  static pten: any = new RegExp(
    /^[A-Za-z0-9\_\-\(\)\uff08\uff09\u4e00-\u9fa5]+$/
  );
  //备注 特殊字符正则
  static bzpten: any = new RegExp(
    /^[A-Za-z0-9\_\-\uff08\uff09\(\)\u4e00-\u9fa5\,\.\?\uff0c\u3002\uff1f\uff1b\;\"\"\'\'\u201c\u201d\u2018\u2019\:\uff1a\u3001\\\/]+$/
  );

  // 导出pdf
  static exportPdf(pdfName) {
    console.log("pdf导出开始");
    debugger;
    //克隆节点，默认为false，不复制方法属性，为true是全部复制。
    var cloneDom = $("#outPdf").clone(true);
    // 添加标题
    // var outTitle = "<div id=\"outTitle\" style=\"font-size:2em;font-weight:bold;text-align:center;\">专家信息导出</div>";
    // cloneDom.prepend(outTitle);
    //设置克隆节点的css属性，因为之前的层级为0，我们只需要比被克隆的节点层级低即可。
    cloneDom.css({
      "background-color": "white",
      position: "absolute",
      top: "0px",
      "z-index": "-1",
    });
    //将克隆节点动态追加到body后面。
    $("body").append(cloneDom);
    html2canvas(cloneDom, {
      allowTaint: true, // 允许跨域
      taintTest: false,
      onrendered: function (canvas) {
        debugger;
        var contentWidth = canvas.width;
        var contentHeight = canvas.height;
        //a4纸的尺寸[595.28,841.89]
        var imgWidth = 555.28;
        //一页pdf显示html页面生成的canvas高度;
        var pageHeight = (contentWidth / imgWidth) * 841.89;
        //未生成pdf的html页面高度
        var leftHeight = contentHeight;
        //pdf页面偏移（第一页上部留20边距）
        var position = 20;
        //a4纸的尺寸[595.28,841.89]，html页面生成的canvas在pdf中图片的宽高
        var imgHeight = (imgWidth / contentWidth) * contentHeight;
        var pageData = canvas.toDataURL("image/jpeg", 1.0);
        var pdf = new jsPDF("", "pt", "a4");
        //有两个高度需要区分，一个是html页面的实际高度，和生成pdf的页面高度(841.89)
        //当内容未超过pdf一页显示的范围，无需分页
        if (leftHeight < pageHeight) {
          pdf.addImage(pageData, "JPEG", 20, position, imgWidth, imgHeight);
        } else {
          while (leftHeight > 0) {
            pdf.addImage(pageData, "JPEG", 20, position, imgWidth, imgHeight);
            leftHeight -= pageHeight;
            position -= 841.89;
            //避免添加空白页
            if (leftHeight > 0) {
              pdf.addPage();
            }
          }
        }
        pdf.save(pdfName + ".pdf");
        cloneDom.remove();
      },
    });
  }

  static getPercentage(num: number): string {
    var strNum = (num * 100).toFixed(0);
    return strNum + "%";
  }
  /**
   * 校验对象中的数据是否有非法字符
   */
  // static patRule: any = /^[a-zA-Z0-9\u4e00-\u9fa5]+$/;
  // static execObject(obj: object): boolean {
  //     debugger
  //     let needBol: boolean = true;
  //     for (let key in obj) {
  //         if (obj.hasOwnProperty(key)) {
  //             let element = obj[key];
  //             if (!this.patRule.test(element) ) {
  //                 return false;
  //             }

  //         }
  //     }
  //     return needBol;
  // }

  /**
   * 银行卡正则校验方法
   */
  static luhnCheck(bankno): boolean {
    let lastNum = bankno.substr(bankno.length - 1, 1); //取出最后一位（与luhn进行比较）
    let first15Num = bankno.substr(0, bankno.length - 1); //前15或18位
    let newArr = new Array();
    for (let i = first15Num.length - 1; i > -1; i--) {
      //前15或18位倒序存进数组
      newArr.push(first15Num.substr(i, 1));
    }
    let arrJiShu = new Array(); //奇数位*2的积 <9
    let arrJiShu2 = new Array(); //奇数位*2的积 >9
    let arrOuShu = new Array(); //偶数位数组
    for (let j = 0; j < newArr.length; j++) {
      if ((j + 1) % 2 == 1) {
        //奇数位
        if (parseInt(newArr[j]) * 2 < 9) arrJiShu.push(parseInt(newArr[j]) * 2);
        else arrJiShu2.push(parseInt(newArr[j]) * 2);
      } //偶数位
      else arrOuShu.push(newArr[j]);
    }

    let jishu_child1 = new Array(); //奇数位*2 >9 的分割之后的数组个位数
    let jishu_child2 = new Array(); //奇数位*2 >9 的分割之后的数组十位数
    for (let h = 0; h < arrJiShu2.length; h++) {
      jishu_child1.push(parseInt(arrJiShu2[h]) % 10);
      jishu_child2.push(parseInt(arrJiShu2[h]) / 10);
    }

    let sumJiShu = 0; //奇数位*2 < 9 的数组之和
    let sumOuShu = 0; //偶数位数组之和
    let sumJiShuChild1 = 0; //奇数位*2 >9 的分割之后的数组个位数之和
    let sumJiShuChild2 = 0; //奇数位*2 >9 的分割之后的数组十位数之和
    let sumTotal = 0;
    for (let m = 0; m < arrJiShu.length; m++) {
      sumJiShu = sumJiShu + parseInt(arrJiShu[m]);
    }

    for (let n = 0; n < arrOuShu.length; n++) {
      sumOuShu = sumOuShu + parseInt(arrOuShu[n]);
    }

    for (var p = 0; p < jishu_child1.length; p++) {
      sumJiShuChild1 = sumJiShuChild1 + parseInt(jishu_child1[p]);
      sumJiShuChild2 = sumJiShuChild2 + parseInt(jishu_child2[p]);
    }
    //计算总和
    sumTotal =
      parseInt(sumJiShu.toLocaleString()) +
      parseInt(sumOuShu.toLocaleString()) +
      parseInt(sumJiShuChild1.toLocaleString()) +
      parseInt(sumJiShuChild2.toLocaleString());

    //计算luhn值
    var k =
      parseInt(sumTotal.toLocaleString()) % 10 == 0
        ? 10
        : parseInt(sumTotal.toLocaleString()) % 10;
    var luhn = 10 - k;

    if (lastNum == luhn) {
      return true;
    } else {
      return false;
    }
  }

  /**
   * 封装FORM表单数据
   * 简化调用的方法名
   *
   * @param data 只能是序列化的字符串, 或者对象
   */
  static wrapForm(data: any): string {
    let form: any[] = Array<any>();
    let ret = {
      items: [],
      itemCount: 0,
      dicts: [],
      resultHint: "",
    };
    try {
      // 是字符串
      if (typeof data == "string") {
        form = JSON.parse(`${data}`);
      }

      // 是数字
      if (typeof data == "number") {
        throw new Error("is number");
      }
      // 是数组
      else if (data instanceof Array) {
        form = data;
      }
      // 是对象
      else if (typeof data == "object") {
        form = [data];
      }
      let itemCount = form.length;
      let items = form;
      Object.assign(ret, { items, itemCount });
      return JSON.stringify(ret);
    } catch (e) {
      throw e;
    }
  }

  /**
   * 简单json对象装换为查询字符串   日期格式以毫秒数返回到后台
   * @Time 2017-12-26
   * @author Zhong Yang
   * @param json 查询Form表单封装成的对象
   */
  static json2Params1(json: object): string {
    let retArr: Array<string> = [];
    let ret: string = "";
    let fmtDateFunc = function (d: Date, fmt: string): string {
      let yyyy = `${d.getFullYear()}`,
        yy = `${yyyy.slice(-2)}`,
        MM = `0${d.getMonth() + 1}`.slice(-2),
        dd = `0${d.getDate()}`.slice(-2),
        hh = `0${d.getHours()}`.slice(-2),
        mm = `0${d.getMinutes()}`.slice(-2),
        ss = `0${d.getSeconds()}`.slice(-2);
      let ret = "";
      ret = fmt.replace(/yyyy/g, yyyy);
      ret = ret.replace(/MM/g, MM);
      ret = ret.replace(/dd/g, dd);
      ret = ret.replace(/hh/g, hh);
      ret = ret.replace(/mm/g, mm);
      ret = ret.replace(/ss/g, ss);

      return ret;
    };
    if (json == null || json == undefined) {
      return ret;
    }

    for (var p in json) {
      if (typeof json[p] == "function") {
        continue;
      }
      let notNull: boolean = this.notNull(json[p]),
        isStringOrNumber =
          typeof json[p] == "string" || typeof json[p] == "number";

      // console.log('isStringOrNumber = ',isStringOrNumber);

      // 参数中,只能是字符串,数字,数组类型;
      if (isStringOrNumber && notNull) {
        let v = json[p];
        // while(v.indexOf("&") >= 0){
        //     v = v.replace("&","%2d9c%");
        // }
        if (typeof json[p] == "string") {
          if (v.indexOf("&") >= 0) {
            v = v.replace(/\&/g, "%2d9c%");
          }
        }

        retArr.push(p + "=" + v);
      }
      // 日期控件
      else if (json[p] instanceof Date && notNull) {
        // 方案1: 时间控件默认以: yyyyMMdd输出
        //let d: string = fmtDateFunc(json[p], 'yyyyMMdd');
        //retArr.push(`${p}=${d}`);
        //方案2: 以毫秒数输出
        retArr.push(p + "=" + json[p].getTime());
      }
      // 数组
      else if (json[p] instanceof Array && notNull && json[p].length) {
        let arrVal: string = json[p].join(",");
        retArr.push(`${p}=${arrVal}`);
      } else {
        notNull &&
          console.log("arry[" + p + "] is not searchFormData property.");
      }
    }
    ret = retArr.join("&");
    return ret;
  }
  /**
   * 非空判断
   * @param value 传来的值
   */
  static notNull(value: any): boolean {
    return value != "" && value != null && value != undefined;
  }

  /**
   * 可编辑DataGrid中的 修改过的数据转变为JSON数组
   * @param gridChangeData 修改过的grid数据
   * @param primaryKey 主键名称
   * @Time 2017-12-27
   * @author Zhong Yang
   * @return void
   */
  static gridChangeData2JSONArr(
    gridChangeData: Array<any>,
    primaryKey: string
  ): Array<Object> {
    let resultBatchItems: any = null;
    let batchRowsData: Array<Object> = new Array<Object>();
    gridChangeData.forEach((rowData) => {
      var keyValue = rowData.key[primaryKey];
      let retArr: Array<string> = [];
      let ret: string = "";
      let newData = rowData.newData;
      retArr.push('"' + primaryKey + '"' + ":" + '"' + keyValue + '"');
      for (var p in newData) {
        let notNull: boolean = this.notNull(newData[p]);
        if (typeof newData[p] == "function" && notNull) {
          continue;
        }
        if (typeof newData[p] == "string" && notNull) {
          retArr.push('"' + p + '"' + ":" + '"' + newData[p] + '"');
        } else if (newData[p] instanceof Date && notNull) {
          retArr.push('"' + p + '"' + ":" + '"' + newData[p].getTime() + '"');
        } else {
          console.log("arry[" + p + "] is not searchFormData property.");
        }
      }
      ret = retArr.join(",");
      batchRowsData.push(JSON.parse("{" + ret + "}"));
    });
    return batchRowsData;
  }
  /**
   * 可编辑DataGrid中的 修改过的数据转变为JSON数组
   * @param gridChangeData 修改过的grid数据
   * @param primaryKey 主键名称
   * @Time 2017-12-27
   * @author Zhong Yang
   * @return void
   */
  static gridChangeData2JSONArr1(
    gridChangeData: Array<any>,
    primaryKey: string,
    primaryKey1: string
  ): Array<Object> {
    let resultBatchItems: any = null;
    let batchRowsData: Array<Object> = new Array<Object>();
    gridChangeData.forEach((rowData) => {
      var keyValue = rowData.key[primaryKey];
      var keyValue1 = rowData.key[primaryKey1];
      let retArr: Array<string> = [];
      let ret: string = "";
      let newData = rowData.newData;
      retArr.push('"' + primaryKey + '"' + ":" + '"' + keyValue + '"');
      retArr.push('"' + primaryKey1 + '"' + ":" + '"' + keyValue1 + '"');
      for (var p in newData) {
        let notNull: boolean = this.notNull(newData[p]);
        if (typeof newData[p] == "function" && notNull) {
          continue;
        }
        if (typeof newData[p] == "string" && notNull) {
          retArr.push('"' + p + '"' + ":" + '"' + newData[p] + '"');
        } else if (newData[p] instanceof Date && notNull) {
          retArr.push('"' + p + '"' + ":" + '"' + newData[p].getTime() + '"');
        } else {
          console.log("arry[" + p + "] is not searchFormData property.");
        }
      }
      ret = retArr.join(",");
      batchRowsData.push(JSON.parse("{" + ret + "}"));
    });
    return batchRowsData;
  }
  /**
   * 可编辑DataGrid中的 修改过的数据转变为JSON数组
   * @param gridChangeData 修改过的grid数据
   * @param primaryKey 主键名称
   * @Time 2017-12-27
   * @author Zhong Yang
   * @return void
   */
  static clearSearchFormData(searchFormData: object): void {
    for (var p in searchFormData) {
      let notNull: boolean =
        searchFormData[p] != null &&
        searchFormData[p] != undefined &&
        searchFormData[p] != "";
      if (typeof searchFormData[p]! == "function" && notNull) {
        continue;
      }
      if (typeof searchFormData[p] == "string" && notNull) {
        searchFormData[p] = null;
      } else if (typeof searchFormData[p] == "number" && notNull) {
        searchFormData[p] = "";
      } else if (searchFormData[p] instanceof Date && notNull) {
        console.log(searchFormData[p]);
        searchFormData[p] = null;
      }
    }

    //解决时间控件无法清空的问题
    $(".dx-datebox.dx-datebox-date.dx-invalid").each(function () {
      $(this).find("input").val("");
      $(this).removeClass("dx-invalid");
    });
  }
  /**
   * 通过primaryKey将传来的数据重新封装
   * 封装成[{primaryKey:value},{primaryKey:value}...]的数组对象
   * @param dataArr 传来的数据 可能是数组  可能是对象类型 （通过 obj.length来判断是哪种类型）
   * @param primaryKey 主键名称
   * @Time 2017-12-27
   * @author Zhong Yang
   * @return void
   */
  static dataArr2IDsArr(
    dataArr: Array<any>,
    primaryKey: string
  ): Array<Object> {
    let resultBatchItems: any = null;
    let batchRowsIDs: Array<Object> = new Array<Object>();
    if (dataArr.length) {
      //数组类型
      for (var items in dataArr) {
        let notNull: boolean = this.notNull(dataArr[items]);
        if (typeof dataArr[items] == "function" && notNull) {
          continue;
        }
        if (typeof dataArr[items] == "object") {
          let tempObj = dataArr[items];
          for (var p in tempObj) {
            if (p == primaryKey) {
              let id = tempObj[p];
              // batchRowsIDs.push(JSON.parse('{"'+ primaryKey +'"'+ ":" +'"'+ tempObj[p] +'"'+'}'));
              batchRowsIDs.push({ [primaryKey]: tempObj[p] });
            }
          }
        }
      }
    } else {
      //对象类型
      for (var p in dataArr) {
        if (p == primaryKey) {
          let id = dataArr[p];
          // batchRowsIDs.push(JSON.parse('{"'+ primaryKey +'"'+ ":" +'"'+ dataArr[p] +'"'+'}'));
          batchRowsIDs.push({ [primaryKey]: dataArr[p] });
        }
      }
    }
    batchRowsIDs.join(",");
    return batchRowsIDs;
  }
  /**
   * 通过primaryKey将传来的数据重新封装
   * 封装成[{primaryKey:value},{primaryKey:value}...]的数组对象
   * @param oldData 修改的全部数据
   * @param primaryKey 主键名称
   * @Time 2017-12-27
   * @author Zhong Yang
   * @return str {主键：主键值}
   */
  static dataArr2IDsStr(dataArr: Array<any>, primaryKey: string): string {
    return JSON.stringify(this.dataArr2IDsArr(dataArr, primaryKey));
  }
  /**
   * 转换修改请求数据
   * @param batchRowsData 修改数据
   * @Time 2017-12-27
   * @author Zhong Yang
   * @return obj
   */
  static strOrArray2UrlParam(batchRowsData: Array<any> | string): string {
    if (batchRowsData instanceof String) {
      try {
        batchRowsData = JSON.parse(batchRowsData);
      } catch (e) {
        console.error("parameterUtils . strOrArray2UrlParam is error");
      }
    }
    let resultBatchItems =
      '{ "items": ' +
      JSON.stringify(batchRowsData) +
      ',"itemCount":"' +
      batchRowsData.length +
      '","dicts":[],"resultHint":""}';
    return resultBatchItems;
  }

  /**
   * 验证from表单提交必填项
   * form 中有 例如：<dxi-validation-rule type="required" message="物料编码不能为空！"></dxi-validation-rule>
   * @param form对象
   */
  static validFormData4Require(form: any): string {
    let items = form.items;
    for (var index in items) {
      let tempItems: any = items[index];
      let validationRules = tempItems.validationRules;
      //不为只读 验证不为空
      if (
        tempItems.editorOptions != undefined &&
        !tempItems.editorOptions.readOnly &&
        ParameterUtils.notNull(validationRules)
      ) {
        if (
          validationRules[0].type == "required" &&
          !validationRules[0].isValid
        ) {
          return validationRules[0].message;
        }
      }
    }
    return "";
  }

  /**
   * 组织查询条件的入参
   * 组装格式如下:
   * {
   *  pageIndex:0,
   *  pageSize:12,
   *  filter:''
   * }
   */
  static loadCondition(loadOptions?: any, formData?: any): string {
    //默认加载方法
    let params: string = "";
    let obj = {
      pageIndex: 1,
      pageSize: 12,
      filter: params,
    };
    try {
      var tmp = formData;
      //当页面初始化调用查询方法时
      if (formData == undefined) {
        // searchForm,此属性loadOptions对象中不存在,存疑
        // tmp = loadOptions.searchForm;
      }
      //组织filter查询条件
      params = ParameterUtils.json2Params1(tmp);
    } catch (ee) {
      console.error("json2Params is error", ee);
    }

    let condi: string = "";
    let o: any = {};
    if (loadOptions != null) {
      let pageIndex = loadOptions.skip
        ? loadOptions.skip / loadOptions.take + 1
        : 1;
      let pageSize = loadOptions.take ? Number.parseInt(loadOptions.take) : 15;
      Object.assign(o, obj, {
        pageIndex: pageIndex,
        pageSize: pageSize,
        filter: params,
      });
    }
    condi = JSON.stringify(o);

    let tmpCondi: string = ParameterUtils.queryEncoder.encodeValue(condi);
    // console.log('initParam', "params="+condi,tmpCondi);
    return `params=${tmpCondi}`;
  } //loadCondition end

  /**
   * 查询请求参数的封闭
   * 包装对象型的查询参数
   * @param params
   * @param loadOptions
   * @param pageIndex
   * @param pageSize
   */
  static wrapParams(
    params: any,
    loadOptions?: any,
    pageIndex?: number,
    pageSize?: number
  ): string {
    //默认加载方法
    let obj = {
      pageIndex: pageIndex || 1,
      pageSize: pageSize || 15,
      filter: "",
    };

    let tmp: any = {};
    if (
      loadOptions != null &&
      loadOptions.skip != null &&
      loadOptions.take != null
    ) {
      var pageIndex = loadOptions.skip / loadOptions.take + 1;
      var pageSize = Number.parseInt(loadOptions.take);
      tmp = Object.assign({}, obj, { pageIndex, pageSize });
      // console.log('paging = ',{pageIndex,pageSize});
    }
    if (params != null) {
      var filter = ParameterUtils.json2Params1(params);
      tmp = Object.assign({}, obj, tmp, { filter });
      // console.log('filter = ',filter,tmp);
    }

    // console.log('tmp = ',tmp);
    let condi = JSON.stringify(tmp);

    let tmpCondi: string = ParameterUtils.queryEncoder.encodeValue(condi);
    // console.log('wrapParams', condi,tmpCondi);
    return `params=${tmpCondi}`;
  }

  /**
   * 包装类型表单
   * @param data
   * @returns [
   *  {},  //form data,只能有一个对象
   *  FILE //FILE file,多个文件
   * ]
   */
  static wrapMultiForm(data: any): Array<any> {
    console.log("wrapMultiForm: ", data);

    let form = [],
      tmpObj = {};
    // console.log('data = ',data);

    let isArray = data instanceof Array;
    // 入参类型
    if (isArray == true) {
      data.map((o, idx, self) => {
        // 是文件对象
        if (o instanceof File) {
          form.push(o);
        }
        // 是文件自定义对象
        else if (typeof o == "object" && o["file"] != null) {
          form.push(o);
        }
        // 是数组
        else if (o instanceof Array && o.length > 0) {
          // 判断首元素是否是File对象
          if (o[0] instanceof File) {
            o.map((f) => {
              form.push(f);
            });
          } else {
            tmpObj[a] = o;
          }
        }
        // 是表单对象
        else {
          // clone对象
          Object.assign(tmpObj, o);
        }
      });
      form.push(tmpObj);
      return form;
    }

    // 入参非数组
    for (var a in data) {
      let tmp = data[a];
      if (tmp == null) {
        // 常规属性
        tmpObj[a] = tmp;
        continue;
      }

      let isFile = tmp instanceof File;
      let isFileObj = typeof tmp == "object" && tmp["file"] != null;
      let isFileArr = tmp instanceof Array && tmp.length > 0;
      if (isFile) {
        // FILE类型的
        form.push(tmp);
      }
      // 是个文件对象
      else if (isFileObj) {
        form.push(tmp["file"]);
      }
      // 是个文件数组
      else if (isFileArr) {
        // 判断首元素是否是File对象
        if (tmp[0] instanceof File) {
          tmp.map((f) => {
            form.push(f);
          });
        } else {
          tmpObj[a] = tmp;
        }
      } else {
        // 常规属性
        tmpObj[a] = tmp;
      }
    }
    form.push(tmpObj);

    // console.log('wrapMultiFormParams', condi);
    return form;
  }
  /**
   * 转换表单时间格式
   * @param data
   * @returns form
   */
  static compareTwoTime(ds: Date, de: Date) {
    if (ds == undefined || de == undefined) {
      return true;
    }
    if (typeof ds == "string" && typeof de == "string") {
      ds = new Date(ParameterUtils.getDateString(ds));
      de = new Date(ParameterUtils.getDateString(de));
    }

    let dsSeconds = ds.getTime();
    let deSeconds = de.getTime();
    if (dsSeconds > deSeconds) {
      return false;
    } else {
      return true;
    }
  }
  static getDateString(d = null): string {
    let fmt = "yyyy-MM-dd hh:mm:ss";
    var now = ParameterUtils.fmtDateFunc(new Date(), fmt);
    if (d == null) return now;

    var tmp: any = new Date(d);
    var ret = now;
    if (tmp != "Invalid Date") {
      ret = ParameterUtils.fmtDateFunc(tmp, fmt);
    }
    return ret;
  }
  static fmtDateFunc(d: Date, fmt: string): string {
    let yyyy = `${d.getFullYear()}`,
      yy = `${yyyy.slice(-2)}`,
      MM = `0${d.getMonth() + 1}`.slice(-2),
      dd = `0${d.getDate()}`.slice(-2),
      hh = `0${d.getHours()}`.slice(-2),
      mm = `0${d.getMinutes()}`.slice(-2),
      ss = `0${d.getSeconds()}`.slice(-2);
    let ret = "";
    ret = fmt.replace(/yyyy/g, yyyy);
    ret = ret.replace(/MM/g, MM);
    ret = ret.replace(/dd/g, dd);
    ret = ret.replace(/hh/g, hh);
    ret = ret.replace(/mm/g, mm);
    ret = ret.replace(/ss/g, ss);

    return ret;
  }
  /**
   * 转换表单时间格式
   * @param data
   * @returns form
   */
  static wrapFormTime(opt: any) {
    let fmtDateFunc = function (d: Date, fmt: string): string {
      let yyyy = `${d.getFullYear()}`,
        yy = `${yyyy.slice(-2)}`,
        MM = `0${d.getMonth() + 1}`.slice(-2),
        dd = `0${d.getDate()}`.slice(-2),
        hh = `0${d.getHours()}`.slice(-2),
        mm = `0${d.getMinutes()}`.slice(-2),
        ss = `0${d.getSeconds()}`.slice(-2);
      let ret = "";
      ret = fmt.replace(/yyyy/g, yyyy);
      ret = ret.replace(/MM/g, MM);
      ret = ret.replace(/dd/g, dd);
      ret = ret.replace(/hh/g, hh);
      ret = ret.replace(/mm/g, mm);
      ret = ret.replace(/ss/g, ss);

      return ret;
    };
    for (var a in opt) {
      let tmp = opt[a];
      if (tmp instanceof Date && this.notNull(tmp)) {
        let t: string = fmtDateFunc(tmp, "yyyyMMdd");
        opt[a] = t;
      }
    }

    return opt;
  }

  /**
   * 判断是否仅选择了一条数据
   * @param dataArray  数据集合
   */
  static isSelectedSingle(dataArray: Array<object>) {
    if (dataArray && dataArray.length == 1) {
      return true;
    }
    notify(
      {
        message: "请选择数据，并且只能选择一条",
        position: {
          my: "center top",
          at: "center top",
        },
      },
      "error",
      3000
    );
    // notify('请选择数据，并且只能选择一条', 'error', 3000);
    return false;
  }

  /**
   * 判断是否勾选
   * @param dataArray  数据集合
   */
  static isSelected(dataArray: Array<object>) {
    if (dataArray && dataArray.length > 0) {
      return true;
    }
    notify(
      {
        message: "请勾选需要选择数据",
        position: {
          my: "center top",
          at: "center top",
        },
      },
      "error",
      3000
    );
    //notify('请勾选需要选择数据', 'error', 3000);
    return false;
  }

  /**
   * 打印
   */
  static preview() {
    let bdhtml = window.document.body.innerHTML; //获取当前页的html代码
    let sprnstr = '<span _ngcontent-c4="" class="startFlag"></span>'; //设置打印开始区域
    let eprnstr = '<span _ngcontent-c4="" class="endFlag"></span>'; //设置打印结束区域
    let prnhtml = bdhtml.substring(bdhtml.indexOf(sprnstr) + sprnstr.length); //从开始代码向后取html
    prnhtml = prnhtml.substring(0, prnhtml.indexOf(eprnstr)); //从结束代码向前取html
    window.document.body.innerHTML = prnhtml;
    window.print();
    window.document.body.innerHTML = bdhtml;
  }

  static preview2(className) {
    $("body > app-root").hide();
    let printDOM = $("." + className).clone();
    $("body").append(printDOM);
    window.print();
    $("body > ." + className).remove();
    $("body > app-root").show();
  }
  static validNullStr(obj) {
    if (obj.constructor === Object) {
      for (var name in obj) {
        if (obj[name] == "null") {
          notify(
            {
              message: "不能输入null字符串!",
              position: {
                my: "center top",
                at: "center top",
              },
            },
            "error",
            3000
          );
          return false;
        }
      }
      return true;
    }
    console.error("参数异常,请传入一个对象,没有就new一个");
    return false;
  }

  /**
   * 浅表复制
   * @param obj
   */
  static copyObj(obj) {
    if (obj instanceof Object) {
      let result = {};
      for (let k in obj) {
        result[k] = obj[k];
      }
      return result;
    }
    return null;
  }

  /**
   * 获取token
   */
  static getToken() {
    let token = ParameterUtils.sessionStorage.getJson("token");
    // 测试时使用
    if (token == null) {
      token = {
        tokenId: "02b70b8d-d344-4556-9515-948fd2c5b5aa",
        sysFlag: "100043004",
      };
      ParameterUtils.sessionStorage.setJson("token", token);
      return null;
    }
    return token["tokenId"];
  }

  /**
   * 获取结束时间,将结束时间改成当天的最后时间23:59:59
   */
  static getEndDay(date) {
    date = new Date(date);
    date.setHours(23);
    date.setMinutes(59);
    date.setSeconds(59);
    date.setMilliseconds(59);
    return date;
  }
  ////判断是否为连续字母
  static checkAdjoinLetter(sPW) {
    var FirstLine = "qwertyuiop[]\\";
    var SecondLine = "asdfghjkl;'";
    var ThirdLine = "zxcvbnm,./";
    var FifthLine = "`1234567890-=";
    var SixLine = "~!@#$%^&*()_+";
    var SevenLine = "1qaz2wsx3edc4rfv5tgb6yhn7ujm8ik,9ol.p;/";
    var EightLine = "7418520963.";
    var NineLine = "1470258.369";
    var TenLine = "IOP{}|";
    var ElevenLine = 'JKL:"';
    var twelthLine = "BNM<>?";
    var ss1 = sPW.split("");
    var str = "";
    if (sPW.length > 3) {
      //判断是否为连续字母
      for (var i = 2; i < sPW.length; i++) {
        str = ss1[i - 2] + ss1[i - 1] + ss1[i];
        if (
          FirstLine.indexOf(str.toLowerCase()) > -1 ||
          SecondLine.indexOf(str.toLowerCase()) > -1 ||
          ThirdLine.indexOf(str.toLowerCase()) > -1 ||
          FifthLine.indexOf(str) > -1 ||
          SixLine.indexOf(str) > -1 ||
          SevenLine.indexOf(str) > -1 ||
          EightLine.indexOf(str) > -1 ||
          NineLine.indexOf(str) > -1 ||
          TenLine.indexOf(str) > -1 ||
          ElevenLine.indexOf(str) > -1 ||
          twelthLine.indexOf(str) > -1
        ) {
          return false;
        }
      }
    }
    return true;
  }
  /**
   * 格式化时间，时分秒
   * @param data
   */
  static dateFormatymdhms(data) {
    var date = new Date(data);
    var Y = date.getFullYear() + "-";
    var M =
      (date.getMonth() + 1 < 10
        ? "0" + (date.getMonth() + 1)
        : date.getMonth() + 1) + "-";
    var D = (date.getDate() < 10 ? "0" + date.getDate() : date.getDate()) + " ";
    var h =
      (date.getHours() < 10 ? "0" + date.getHours() : date.getHours()) + ":";
    var m =
      (date.getMinutes() < 10 ? "0" + date.getMinutes() : date.getMinutes()) +
      ":";
    var s =
      date.getSeconds() < 10 ? "0" + date.getSeconds() : date.getSeconds();
    return Y + M + D + h + m + s;
  }
  /**
   * 获取今天0点的毫秒数
   */
  static getToday(): Date {
    var date = new Date(); //获取当前Date对象
    date.setHours(0);
    date.setMinutes(0);
    date.setSeconds(0);
    date.setMilliseconds(0);
    //获取毫秒时间戳，（1970-01-01 00:00:00到现在的毫秒数）
    // var timestamp = date.getTime();
    return date;
  }
  /**
   * 获取时间，时分秒为0
   */
  static getDateYmd(time): Date {
    var date = new Date(time); //获取当前Date对象
    date.setHours(0);
    date.setMinutes(0);
    date.setSeconds(0);
    date.setMilliseconds(0);
    return date;
  }
  /**
   * 获取当前日期后一天的时间，时分秒为0
   */
  static getNextDateYmd(time): Date {
    var curDate = new Date(time); //获取当前Date对象
    var nextDate = new Date(curDate.getTime() + 24 * 60 * 60 * 1000);
    nextDate.setHours(0);
    nextDate.setMinutes(0);
    nextDate.setSeconds(0);
    nextDate.setMilliseconds(0);
    return nextDate;
  }

  /**
   * 转换对象中的日期属性为毫秒
   *
   * @author niushengsheng
   */
  static transBean(bean: any) {
    for (var p in bean) {
      // 匹配到日期类型的属性
      if (p.search(/.*Time$/) > -1) {
        var val = bean[p];
        // 时间类型
        if (val instanceof Date) {
          bean[p] = val.getTime();
        }
        //字符串
        else {
          try {
            bean[p] = new Date(val).getTime();
            //校正时间
            if (bean[p] == 0) {
              bean[p] = new Date().getTime();
            }
          } catch (e) {
            bean[p] = new Date().getTime();
          }
        }
      }
    }

    return bean;
  }

  /**
   * 获取UUID
   */
  static getUUID() {
    return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (
      c
    ) {
      var r = (Math.random() * 16) | 0,
        v = c == "x" ? r : (r & 0x3) | 0x8;
      return v.toString(16);
    });
  }
}
